Webpack实践

2020.11.22 星期 :

webpack-chain

webpack-chain: https://github.com/neutrinojs/webpack-chain/tree/v4

使用toString()查看chain对应的webpack配置

配置

public path

可以修改运行时路径 - 动态资源路径。
webpack_public_path: https://webpack.docschina.org/guides/public-path/

qiankun.js: 使用 webpack 运行时 publicPath 配置

runtime publicPath 主要解决的是微应用动态载入的 脚本、样式、图片 等地址不正确的问题。

动态修改publicPath 只需要在入口文件顶一下webpack_require.p这个变量值即可,webpack在做ast解析的时候会特殊处理这个webpack_require这个变量,

场景一:
静态资源都上传到oss。在webpack.config.js 文件中定义好publicPath 就没问题了。
但是taro项目/平台的云构建,并没有替换掉chunck 文件的路径。
所以,需要我们修改运行时public path;

场景二:
资源文件添加了域名兜底处理onrrror=”__reloadResource(this)”;
app.js 可以加载新域名。但是chunk 文件并没 添加onrrror(webpack-html-plugin);直接加载兜底域名的资源就可以了。

1
2
3
4
5
6
7
8
9
10
11
// 兜底域名reload resouce 处理。
function getAsyncPublicPath () {
// console.log('get AsyncPublic Path', location)
if (process.env.TARO_ENV === "h5" && process.env.NODE_ENV === "production") {
const appjss = document.querySelectorAll("[src*='app.']");
if (appjss.length > 1) {
__webpack_public_path__ = "//jstatic2.3.cn/";
}
}
};
getAsyncPublicPath();

Note: 需要在app.js 的顶部引入。

插件

terser-webpack-plugin

  1. chain.optimization.minimizer('terserPlugin')
  2. 由于Webpack5已经集成terser-webpack-plugin,无需单独安装,直接引入
  3. extractComments默认为true,所以会将注释提取到单独的文件中,生成LICENSE文件。
    1
    2
    3
    chain.plugin("terserWebpackPlugin").use(new TerserPlugin({
    extractComments: false, //不将注释提取到单独的文件中
    }))
1
Whether comments shall be extracted to a separate file, (see details). By default extract only comments using /^\**!|@preserve|@license|@cc_on/i regexp condition and remove remaining comments. If the original file is named foo.js, then the comments will be stored to foo.js.LICENSE.txt. The terserOptions.format.comments option specifies whether the comment will be preserved, i.e. it is possible to preserve some comments (e.g. annotations) while extracting others or even preserving comments that have been extracted.

html-webpack-plugin

html-webpack-plugin: https://github.com/jantimon/html-webpack-plugin#options

  1. chain中使用 chain.plugin("htmlWebpackPlugin")
  2. 单页应用需要生成多个html(url访问),可以添加多个插件实例。
  3. filename 可以写路径,会把文件写到对应路径下面,比如my/cart/main.shtml
  4. 在资源标签上添加onerror属性。<script src="//xxx.m.cn/js/app.8b9dbe4febbbf0233339.js" onerror="__reloadResource(this)"></script>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    const HtmlWebpackPlugin = require('html-webpack-plugin')

    /**
    * 基于html-webpack-plugin。
    * 在资源标签上添加onerror属性。
    */
    class HtmlAssetsReload {
    apply (compiler) {
    compiler.hooks.compilation.tap('HtmlAssetsReload', (compilation) => {
    HtmlWebpackPlugin.getHooks(compilation).alterAssetTags.tapAsync("HtmlAssetsReload", (data, cb) => {
    const {assetTags: {scripts, styles}} = data;
    // console.log('HtmlAssetsReload:', scripts, styles)
    scripts.forEach(v => v.attributes.onerror = "__reloadResource(this)")
    styles.forEach(v => v.attributes.onerror = "__reloadResource(this)")
    cb(null, data)
    });
    })
    }
    }

    module.exports = HtmlAssetsReload

ssi-mini-webpack-plugin: https://www.npmjs.com/package/ssi-webpack-plugin/v/1.0.8
静态编译ssi资源

性能分析

官方:performance,stats

ProgressBarPlugin
npm i progress-bar-webpack-plugin

SpeedMeasurePlugin
npm i speed-measure-webpack-plugin
https://github.com/stephencookdev/speed-measure-webpack-plugin

BundleAnalyzerPlugin
npm i webpack-bundle-analyzer

DashboardPlugin
npm i webpack-dashboard

DuplicatePackageCheckerPlugin
npm i duplicate-package-checker-webpack-plugin

忽略一些特定warnings

"export 'W_jdgwxcx_BannerExpo' (imported as 'wEPoint') was not found in '@/points/epoint-follow'

webpack配置。

大多是webapck5支持。
taro3.4 还没有complie: webpack5(3.6)支持。默认是webpack4.
所以配置还是失败了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
module.exports = {
// ## 4 难道是devServer 中的配置吗? build时候没有
devServer: {
quiet: true,
noInfo: true,
stats: 'errors-only',
// 新版本有的
client: {
logging: 'error',
},
},
webpackChain (chain, webpack) {
// chain.plugin('webpackHotMiddleware')
// .tap(args => {
// console.log('plugin ', args)
// // 该插件这么修改会报错
// // args.push({log: false})
// return [{log: false}]
// })


// ## 0 报错不会运行
// chain.plugin('FilterWarningsPlugin')
// .use(FilterWarningsPlugin, {
// exclude: /export 'W_jdgwxcx_.*was not found in .*/,
// })

// ## 7 清空所有error: `clear:true`。不符合
// chain.plugin('FriendlyErrorsWebpackPlugin')
// .use(FriendlyErrorsWebpackPlugin)

chain.merge({
// module: {
// // ## 1 webpack5 支持。但是是所有
// strictExportPresence: false,
// parser: {
// javascript: {
// reexportExportsPresence: false,
// importExportsPresence: false,
// exportsPresence: false,
// },
// },
// },
// ## 3 stats 设置,并没有阻止掉dev时候的输出。
stats: {
// ### 3-1
warnings: false,
// ### 3-2
logging: 'none',
// ## 3-3 excludeModules/exclude 设置
excludeModules: [
/ea-point-.*/,
/reports\/ea-points\/ea-point-.*/,
],
// ## 2-1 stats.warningsFilter 已被弃用,请改用 ignoreWarnings。
warningsFilter: [
/ea-point-.*/,
/reports\/ea-points\/ea-point-.*/,
],
},
// ### 3-0
// stats: 'errors-only',
// ## 2 忽略掉特定的警告。
// ignoreWarnings: [
// /ea-point-.*/,
// /reports\/ea-points\/ea-point-.*/,
// ],
})
}
}

FINALLY:解决上面问题(trao 多文件导出),用了最笨的方式:乖乖的导出。

webpack-filter-warnings-plugin

webpack-filter-warnings-plugin: https://github.com/mattlewis92/webpack-filter-warnings-plugin/issues/35

@iegik Webpack 5 doesn’t need this plugin anymore. You can use ignoreWarnings:

PS: taro3.4 的版本中失效了。应该是指定的webapck 版本才支持。 用webpack chain 的写法,运行失败了。

1
2
3
4
5
6
7
8
9
10
11
12
const FilterWarningsPlugin = require("webpack-filter-warnings-plugin");

exports.onCreateWebpackConfig = ({ actions }) => {
actions.setWebpackConfig({
plugins: [
new FilterWarningsPlugin({
exclude:
/mini-css-extract-plugin[^]*Conflicting order. Following module has been added:/,
}),
],
});
};

FriendlyErrorsWebpackPlugin

friendly-errors-webpack-plugin: https://www.npmjs.com/package/friendly-errors-webpack-plugin


于是参考了vue-cli的配置,使用FriendlyErrorsWebpackPlugin插件来解决这个问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
module.exports = {
devServer: {
quiet: true, // 如果使用webpack-dev-server,需要设为true,禁止显示devServer的console信息
},
plugins: [
new FriendlyErrorsWebpackPlugin({
compilationSuccessInfo: {
messages: [`Your application is running here: ${config.dev.https ? 'https' : 'http'}://${config.dev.host}:${config.dev.port}`],
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined,
clearConsole: true,
}),
],
}

mini-css-extract-plugin

Conflicting order. Following module has been added:
此警告意思为在不同的js中引用相同的css时,先后顺序不一致。也就是说,在1.js中先后引入a.css和b.css,而在2.js中引入的却是b.css和a.css,此时会有这个warning。

直接修改顺序可以避免这个警告,但是后期所有的文件顺序都得按照这个来,有些繁琐。
增加ignoreOrder: true配置,如:

1
2
3
4
5
6
7
8
9
10
11
12
new MiniCssExtractPlugin({
// ......
ignoreOrder: true
}),
// webpack chain
webpackChain (chain) {
chain.plugin('miniCssExtractPlugin')
.tap(args => {
args[0].ignoreOrder = true
return args
})
}

问题

  1. Conflicting order. Following module has been added:
    见插件:mini-css-extract-plugin

knowledge is no pay,reward is kindness
0%